namespace Leey.Net.eTerm
{
    using Leey.Net.eTerm.Net;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Net.Sockets;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Timers;

    public class EtermConnection
    {
        private bool autoreconnect = true;
        private int autoreconnectinterval = 0x1388;
        private bool autosi = true;
        private bool bKeepAlive = true;
        private string chkcode = "";
        private short cmdindex = 0;
        private Queue cmdqueue = new Queue();
        private System.Threading.Timer connectTimeoutTimer;
        private ManualResetEvent continunextcmd = new ManualResetEvent(false);
        private Packet currentcmdpacket = null;
        private TerminalType eterminaltype;
        private int exeinterval = 0;
        private bool hasAuGetPrice = false;
        private bool hasN = false;
        private bool is3in1 = false;
        private bool keepreconnect = false;
        private ManualResetEvent keydone = new ManualResetEvent(false);
        private string keylogin = "";
        private int length = 0;
        private byte[] loginByte = null;
        private LoginSteps lss = null;
        private ClientSocket m_ClientSocket = null;
        public StateClass.ConnectionState m_ConnectionState = StateClass.ConnectionState.DisConnected;
        private bool m_ConnectTimedOut = false;
        private long m_ConnectTimeout = 0x61a8L;
        private StateClass.LoginState m_LoginState = StateClass.LoginState.UnLogined;
        private StreamParser m_StreamParser = null;
        private short numsetp = 0;
        private Packet parentcmdpacket = null;
        private string password;
        private int port;
        private bool refreshchkcode = false;
        private bool sendLoginStep2 = false;
        private string server;
        private string sitext = "";
        private bool ssl;
        private byte[] tempdata = new byte[0x9d];
        private StringBuilder tempfullpacket = new StringBuilder();
        private System.Timers.Timer tKeepAlive = new System.Timers.Timer();
        private System.Timers.Timer tReConnect = new System.Timers.Timer();
        private string username;

        public event CmdCountChangeHandler OnCmdCountChange;

        public event ErrorHandler OnError;

        public event EtermConnectionStateHandler OnEtermConnectionStateChanged;

        public event ChkCodeHandler OnGetChkCode;

        public event LoginInfoHandler OnGetLoginInfo;

        public event ObjectHandler OnLogin;

        public event CmdResultHandler OnReadPacket;

        public event BaseSocket.OnSocketDataHandler OnReadSocketData;

        public event PacketHandler OnSendPacket;

        public event ObjectHandler OnUnLogin;

        public event BaseSocket.OnSocketDataHandler OnWriteSocketData;

        public EtermConnection()
        {
            this.tKeepAlive.Elapsed += new ElapsedEventHandler(this.tKeepAlive_Elapsed);
            this.tReConnect.Elapsed += new ElapsedEventHandler(this.tReConnect_Elapsed);
            this.m_StreamParser = new StreamParser();
            this.m_StreamParser.OnStreamElement += new StreamHandler(this.StreamParserOnStreamElement);
            this.m_StreamParser.OnStreamError += new StreamError(this.StreamParserOnStreamError);
            this.lss = new LoginSteps();
        }

        public int BusyLevel()
        {
            return this.cmdqueue.Count;
        }

        public void Close()
        {
            this.m_ClientSocket.OnConnect -= new ObjectHandler(this.SocketOnConnect);
            this.m_ClientSocket.OnDisconnect -= new ObjectHandler(this.SocketOnDisconnect);
            this.m_ClientSocket.OnSend -= new BaseSocket.OnSocketDataHandler(this.m_ClientSocket_OnSend);
            this.m_ClientSocket.OnReceive -= new BaseSocket.OnSocketDataHandler(this.SocketOnReceive);
            this.m_ClientSocket.OnError -= new ErrorHandler(this.SocketOnError);
            if (this.m_ClientSocket != null)
            {
                this.m_ClientSocket.Disconnect();
            }
            this.m_StreamParser.Reset();
            this.connectTimeoutTimer.Dispose();
            this.tKeepAlive.Stop();
            this.DoChangeEtermConnectionState(StateClass.ConnectionState.DisConnected);
        }

        public void CloseAll()
        {
            this.tReConnect.Stop();
            this.Close();
        }

        private void connectTimeoutTimerDelegate(object stateInfo)
        {
            this.connectTimeoutTimer.Dispose();
            this.m_ConnectTimedOut = true;
            this.Close();
        }

        internal void DoChangeEtermConnectionState(StateClass.ConnectionState state)
        {
            this.m_ConnectionState = state;
            if (this.OnEtermConnectionStateChanged != null)
            {
                this.OnEtermConnectionStateChanged(this, state);
            }
        }

        private void ExeCmd(object state)
        {
            EtermConnection connection;
            while (this.m_ConnectionState == StateClass.ConnectionState.Logined)
            {
                if (((this.cmdqueue.Count > 0) || ((this.currentcmdpacket != null) && (this.currentcmdpacket.SubCmdPacket != null))) || ((this.currentcmdpacket != null) && this.CurrentCmdPacket.Repeat))
                {
                    if (((this.currentcmdpacket != null) && !this.CurrentCmdPacket.Repeat) && (this.currentcmdpacket.SubCmdPacket != null))
                    {
                        this.currentcmdpacket = this.currentcmdpacket.SubCmdPacket;
                    }
                    else if ((this.currentcmdpacket != null) && this.CurrentCmdPacket.Repeat)
                    {
                        this.CurrentCmdPacket.Repeat = false;
                    }
                    else
                    {
                        lock ((connection = this))
                        {
                            if (this.cmdqueue.Count > 0)
                            {
                                this.tempfullpacket.Remove(0, this.tempfullpacket.Length);
                                this.currentcmdpacket = this.cmdqueue.Dequeue() as Packet;
                                this.parentcmdpacket = this.currentcmdpacket;
                                this.FireOnCmdCountChange(this, this.BusyLevel());
                            }
                        }
                    }
                    if (this.currentcmdpacket == null)
                    {
                        continue;
                    }
                    this.continunextcmd.Reset();
                    Thread.Sleep(this.ExeInterval);
                    this.m_ClientSocket.Send(this.currentcmdpacket.EncodeCmdBytes);
                    this.tKeepAlive.Stop();
                    this.tKeepAlive.Start();
                    this.FireOnSendText(this, this.currentcmdpacket);
                    this.continunextcmd.WaitOne();
                }
                else
                {
                    Thread.Sleep(100);
                }
            }
            while (this.cmdqueue.Count > 0)
            {
                CmdPacket packet;
                lock ((connection = this))
                {
                    packet = this.cmdqueue.Dequeue() as CmdPacket;
                }
                this.PostErroResult(packet);
            }
        }

        protected void FireOnCmdCountChange(object sender, int count)
        {
            if (this.OnCmdCountChange != null)
            {
                this.OnCmdCountChange(sender, count);
            }
        }

        protected void FireOnError(object sender, Exception ex)
        {
            this.Close();
            if (this.OnError != null)
            {
                this.OnError(sender, ex);
            }
        }

        protected void FireOnGetChkCode(object sender, Image i)
        {
            if (this.OnGetChkCode != null)
            {
                this.OnGetChkCode(sender, i);
            }
        }

        protected void FireOnGetLoginInfo(object sender, string username, string password)
        {
            if (this.OnGetLoginInfo != null)
            {
                this.OnGetLoginInfo(sender, username, password);
            }
        }

        protected void FireOnLogin(object sender)
        {
            if (this.m_ConnectTimedOut)
            {
                this.Close();
                this.FireOnError(null, new ConnectTimeoutException("Attempt to connect timed out"));
            }
            else
            {
                this.connectTimeoutTimer.Dispose();
                this.tReConnect.Interval = this.AutoReConnectInterval;
                this.tReConnect.Start();
                if (this.bKeepAlive)
                {
                    this.tKeepAlive.Interval = 300000.0;
                    this.tKeepAlive.Enabled = true;
                }
                if (this.OnLogin != null)
                {
                    this.OnLogin(sender);
                }
                ThreadPool.QueueUserWorkItem(new WaitCallback(this.ExeCmd));
            }
        }

        protected void FireOnReadText(object sender, CmdResult e)
        {
            if (this.OnReadPacket != null)
            {
                this.OnReadPacket(sender, e);
            }
        }

        protected void FireOnSendText(object sender, Packet e)
        {
            if (this.OnSendPacket != null)
            {
                this.OnSendPacket(sender, e);
            }
        }

        protected void FireOnUnLogin(object sender)
        {
            if (this.OnUnLogin != null)
            {
                this.OnUnLogin(sender);
            }
        }

        private Image GetWebImage(string s)
        {
            int num2;
            bool flag = true;
            bool flag2 = false;
            List<byte> list = new List<byte>();
            byte[] bytes = Encoding.ASCII.GetBytes(s);
            TcpClient client = new TcpClient();
            do
            {
                try
                {
                    client.Connect("219.142.127.25", 80);
                    flag2 = true;
                }
                catch
                {
                    flag2 = false;
                }
                Thread.Sleep(500);
            }
            while (this.KeepReconnect && !flag2);
            NetworkStream stream = client.GetStream();
            stream.Write(bytes, 0, bytes.Length);
            byte[] buffer = new byte[0x400];
            StringBuilder builder = new StringBuilder();
            int num = 0;
            do
            {
                num = stream.Read(buffer, 0, buffer.Length);
                num2 = 0;
                while (num2 < (num - 1))
                {
                    list.Add(buffer[num2]);
                    num2++;
                }
                if ((buffer[num - 2] == 0xff) && (buffer[num - 1] == 0xd9))
                {
                    flag = false;
                }
            }
            while (flag || stream.DataAvailable);
            int num3 = 0;
            for (num2 = 0; num2 < (list.Count - 2); num2++)
            {
                if ((list[num2] == 0xff) && (list[num2 + 1] == 0xd8))
                {
                    num3 = num2;
                }
            }
            byte[] buffer3 = new byte[list.Count - num3];
            for (num2 = 0; num2 < ((list.Count - num3) - 1); num2++)
            {
                buffer3[num2] = list[num3 + num2];
            }
            Image i = Image.FromStream(new MemoryStream(buffer3));
            this.FireOnGetChkCode(this, i);
            return i;
        }

        private void InitSocket()
        {
            this.m_ClientSocket = new ClientSocket();
            this.m_ClientSocket.SendNoResponseInterval = this.SendNoResponseInterval;
            this.m_ClientSocket.OnConnect += new ObjectHandler(this.SocketOnConnect);
            this.m_ClientSocket.OnDisconnect += new ObjectHandler(this.SocketOnDisconnect);
            this.m_ClientSocket.OnSend += new BaseSocket.OnSocketDataHandler(this.m_ClientSocket_OnSend);
            this.m_ClientSocket.OnReceive += new BaseSocket.OnSocketDataHandler(this.SocketOnReceive);
            this.m_ClientSocket.OnError += new ErrorHandler(this.SocketOnError);
        }

        private void iTermOpen(object sender)
        {
            string s = "GET / HTTP/1.1\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 2.0.50727)\r\nHost: web.travelsky.com\r\nConnection: Keep-Alive\r\n\r\n";
            WebReturnInfo info = new WebReturnInfo(this.LoginStep(s, false));
            if (info.StateCode != "200 OK")
            {
                this.FireOnError(this, new Exception("wri1失败"));
            }
            else
            {
                string str2 = string.Format("GET /APS/portal/Iterm302.jsp HTTP/1.1\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*\r\nReferer: http://web.travelsky.com/\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 2.0.50727)\r\nHost: web.travelsky.com\r\nConnection: Keep-Alive\r\nCookie: {0}\r\n\r\n", info.WebHeaders["Set-Cookie"].ToString().Split(new char[] { ';' })[0]);
                WebReturnInfo info2 = new WebReturnInfo(this.LoginStep(str2, false));
                if (info2.StateCode != "302 Found")
                {
                    this.FireOnError(this, new Exception("wri2失败"));
                }
                else
                {
                    string str3 = string.Format("GET /APS/servlet/portal.Main HTTP/1.1\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*\r\nReferer: http://web.travelsky.com/\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 2.0.50727)\r\nHost: web.travelsky.com\r\nConnection: Keep-Alive\r\nCookie: {0}; {1}\r\n\r\n", info.WebHeaders["Set-Cookie"].ToString().Split(new char[] { ';' })[0], info2.WebHeaders["Set-cookie"].ToString().Split(new char[] { ';' })[0]);
                    WebReturnInfoEx ex = new WebReturnInfoEx(this.LoginStep(str3, true));
                    if (ex.SecurityCode == "")
                    {
                        this.FireOnError(this, new Exception("取得安全码失败"));
                    }
                    else
                    {
                        string str4 = string.Format("GET /APS/servlet/portal.CheckCodeImage HTTP/1.1\r\nAccept: */*\r\nReferer: http://web.travelsky.com/APS/servlet/portal.Main\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 2.0.50727)\r\nHost: web.travelsky.com\r\nConnection: Keep-Alive\r\nCookie: {0}; {1}\r\n\r\n", info.WebHeaders["Set-Cookie"].ToString().Split(new char[] { ';' })[0], info2.WebHeaders["Set-cookie"].ToString().Split(new char[] { ';' })[0]);
                        for (Image image = this.GetWebImage(str4); this.RefreshChkCode; image = this.GetWebImage(str4))
                        {
                            this.RefreshChkCode = false;
                        }
                        if (this.ChkCode == "")
                        {
                            this.FireOnError(this, new Exception("需要验证码"));
                        }
                        else
                        {
                            string str5 = string.Format("username={0}&password={1}&chkCode={2}&securitycode={3}", new object[] { this.UserName, this.PassWord, this.ChkCode, ex.SecurityCode });
                            string str6 = string.Format("POST /APS/servlet/portal.Login HTTP/1.1\r\nAccept: */*\r\nContent-Type: application/x-www-form-urlencoded\r\nReferer: http://web.travelsky.com/APS/servlet/portal.Main\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 2.0.50727)\r\nHost: web.travelsky.com\r\nContent-Length: {0}\r\nConnection: Keep-Alive\r\nCache-Control: no-cache\r\nCookie: {1}; {2}; Cookie_itsun_1611296=y\r\n\r\n", str5.Length.ToString(), info.WebHeaders["Set-Cookie"].ToString().Split(new char[] { ';' })[0], info2.WebHeaders["Set-cookie"].ToString().Split(new char[] { ';' })[0]) + str5;
                            WebReturnInfo info3 = new WebReturnInfo(this.LoginStep(str6, false));
                            if (!info3.WebHeaders["Location"].ToString().Contains("Iterm305.jsp"))
                            {
                                this.FireOnError(this, new Exception("外部帐号登陆失败，不能取得Iterm305.jsp页面"));
                            }
                            else
                            {
                                string str7 = string.Format("GET /APS/portal/Iterm305.jsp HTTP/1.1\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*\r\nReferer: http://web.travelsky.com/APS/servlet/portal.Main\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 2.0.50727)\r\nHost: web.travelsky.com\r\nConnection: Keep-Alive\r\nCache-Control: no-cache\r\nCookie: Cookie_itsun_1611296=y; {0}; {1}\r\n\r\n", info.WebHeaders["Set-Cookie"].ToString().Split(new char[] { ';' })[0], info2.WebHeaders["Set-cookie"].ToString().Split(new char[] { ';' })[0]);
                                WebReturnInfoExLogin login = new WebReturnInfoExLogin(this.LoginStep(str7, true));
                                if ((login.Username == "") || (login.Password == ""))
                                {
                                    this.FireOnError(this, new Exception("读取内部帐号密码失败"));
                                }
                                else
                                {
                                    this.FireOnGetLoginInfo(null, login.Username, login.Password);
                                    this.UserName = login.Username;
                                    this.PassWord = login.Password;
                                    this.m_ClientSocket.Connect();
                                }
                            }
                        }
                    }
                }
            }
        }

        private void KeepAlive()
        {
            byte[] bData = Command.StringToBytes("01 fb 00 05 00");
            this.m_ClientSocket.Send(bData);
        }

        private string LoginStep(string s, bool waitforhtml)
        {
            bool flag = false;
            List<byte> list = new List<byte>();
            list.AddRange(Encoding.ASCII.GetBytes(s));
            TcpClient client = new TcpClient();
            do
            {
                try
                {
                    client.Connect(this.Server, this.Port);
                    flag = true;
                }
                catch (Exception exception)
                {
                    flag = false;
                    if (!this.KeepReconnect)
                    {
                        this.FireOnError(this, exception);
                        return "";
                    }
                    Thread.Sleep(0x3e8);
                }
            }
            while (this.KeepReconnect && !flag);
            NetworkStream stream = client.GetStream();
            stream.Write(list.ToArray(), 0, list.Count);
            byte[] buffer = new byte[0x400];
            StringBuilder builder = new StringBuilder();
            int count = 0;
            do
            {
                count = stream.Read(buffer, 0, buffer.Length);
                builder.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, count));
            }
            while ((waitforhtml && !builder.ToString().Contains("</html>")) || stream.DataAvailable);
            return builder.ToString();
        }

        internal virtual void m_ClientSocket_OnSend(object sender, byte[] data, int count)
        {
        }

        public void Open()
        {
            if (((!(this.Server.Trim() != "") || (this.Port == 0)) || !(this.UserName.Trim() != "")) || !(this.PassWord.Trim() != ""))
            {
                throw new Exception("请先设置Server,Port,UserName,PassWord相关属性");
            }
            this.Open(this.server, this.port, this.ssl, this.username, this.password);
        }

        private void Open(string server, int port, string username, string password)
        {
            this.Open(server, port, this.m_ClientSocket.SSL, username, password);
        }

        public void Open(string server, int port, bool ssl, string username, string password)
        {
            if (this.m_ConnectionState == StateClass.ConnectionState.DisConnected)
            {
                this.InitSocket();
                this.DoChangeEtermConnectionState(StateClass.ConnectionState.Connecting);
                this.Server = server;
                this.Port = port;
                this.UserName = username;
                this.PassWord = password;
                this.Ssl = ssl;
                this.m_ClientSocket.SSL = ssl;
                this.m_ConnectTimedOut = false;
                TimerCallback callback = new TimerCallback(this.connectTimeoutTimerDelegate);
                this.connectTimeoutTimer = new System.Threading.Timer(callback, null, this.ConnectTimeout, this.ConnectTimeout);
                if (this.eTerminalType == TerminalType.iTerm)
                {
                    this.m_ClientSocket.Address = "219.142.127.18";
                    this.m_ClientSocket.Port = 350;
                    ThreadPool.QueueUserWorkItem(new WaitCallback(this.iTermOpen));
                }
                else if (this.eTerminalType == TerminalType.eTerm)
                {
                    this.m_ClientSocket.Address = this.Server;
                    this.m_ClientSocket.Port = this.Port;
                    this.m_ClientSocket.Connect();
                }
                else
                {
                    this.FireOnError(this, new Exception("请指定连接类型.目前支持eTerm,iTerm"));
                }
            }
        }

        private void PostErroResult(Packet cmd)
        {
            CmdResult e = new CmdResult();
            e.Data = "连接已断开";
            e.CmdPacket = cmd;
            this.StreamParserOnStreamElement(null, e);
        }

        private void ReConnect()
        {
            if (this.AutoReConnect && (this.m_ConnectionState == StateClass.ConnectionState.DisConnected))
            {
                this.Open(this.Server, this.Port, this.UserName, this.PassWord);
            }
        }

        private void SendCmd(byte[] cmd)
        {
            this.m_ClientSocket.Send(cmd);
        }

        public void SendCmd(Packet cmd)
        {
            if (this.m_ConnectionState != StateClass.ConnectionState.Logined)
            {
                this.PostErroResult(cmd);
            }
            else
            {
                lock (this)
                {
                    this.cmdqueue.Enqueue(cmd);
                }
                this.FireOnCmdCountChange(this, this.BusyLevel());
            }
        }

        internal virtual void SocketOnConnect(object sender)
        {
            this.DoChangeEtermConnectionState(StateClass.ConnectionState.Connected);
            Thread.Sleep(0x3e8);
            this.DoChangeEtermConnectionState(StateClass.ConnectionState.Logining);
            this.m_LoginState = StateClass.LoginState.LoginStep1;
            this.SendCmd(this.lss.LoginStep1(this.UserName, this.PassWord));
        }

        internal virtual void SocketOnDisconnect(object sender)
        {
            this.Close();
            this.FireOnUnLogin(this);
        }

        internal virtual void SocketOnError(object sender, Exception ex)
        {
            this.Close();
            this.FireOnError(sender, ex);
        }

        internal virtual void SocketOnReceive(object sender, byte[] data, int count)
        {
            if (this.m_ConnectionState == StateClass.ConnectionState.Logined)
            {
                if (this.OnReadSocketData != null)
                {
                    this.OnReadSocketData(sender, data, count);
                }
                lock (this)
                {
                    this.m_StreamParser.Push(data, 0, count);
                }
            }
            else
            {
                CmdPacket packet;
                if (((count == 0x84) || (count == 0x98)) || (count == 0x9d))
                {
                    this.sendLoginStep2 = true;
                }
                switch (this.m_LoginState)
                {
                    case StateClass.LoginState.LoginStep1:
                        this.m_LoginState = StateClass.LoginState.LoginStep2;
                        if (((data[0] != 0) || (data[1] != 0x20)) || (data[2] != 0))
                        {
                            if (this.m_ClientSocket.SSL)
                            {
                                if (count < 0x80)
                                {
                                    Buffer.BlockCopy(data, 0, this.tempdata, 0, count);
                                    this.m_LoginState = StateClass.LoginState.LoginStep1;
                                    this.length = count;
                                    return;
                                }
                                if (count == 0x84)
                                {
                                    Buffer.BlockCopy(data, 0, this.tempdata, this.length, count);
                                }
                                else if (count == 0x98)
                                {
                                    Buffer.BlockCopy(data, 0, this.tempdata, 0, count);
                                }
                                else if (count == 0x9d)
                                {
                                    Buffer.BlockCopy(data, 0, this.tempdata, 0, count);
                                }
                            }
                            else
                            {
                                Buffer.BlockCopy(data, 0, this.tempdata, 0, count);
                            }
                            this.LoginByte = new byte[2];
                            this.LoginByte[0] = this.tempdata[8];
                            if ((this.tempdata[9] & 0x80) != 0)
                            {
                                this.LoginByte[1] = Convert.ToByte((int) (this.tempdata[9] ^ 0x80));
                            }
                            else
                            {
                                this.LoginByte[1] = this.tempdata[9];
                            }
                            if (this.m_ClientSocket.SSL)
                            {
                                byte[] buffer;
                                byte[] buffer2;
                                int num;
                                if ((this.tempdata[0] == 0) && (this.tempdata[1] != 0))
                                {
                                    buffer = new byte[0x80];
                                    buffer2 = new byte[0x80];
                                    for (num = 0; num < 0x80; num++)
                                    {
                                        buffer[num] = this.tempdata[(num + this.tempdata[1]) + 4];
                                    }
                                    if ((((buffer[0] == 0) && (buffer[1] == 0)) && (buffer[2] == 0)) && (buffer[3] == 0))
                                    {
                                        this.m_LoginState = StateClass.LoginState.LoginStep1;
                                        return;
                                    }
                                    eTermEncode.Encropy(buffer, buffer2);
                                    this.SendCmd(this.lss.LoginStep2(buffer2));
                                }
                                else if ((this.tempdata[0] == 1) && (this.tempdata[1] == 0xf6))
                                {
                                    buffer = new byte[0x80];
                                    buffer2 = new byte[0x80];
                                    for (num = 0; num < 0x80; num++)
                                    {
                                        buffer[num] = this.tempdata[num + 4];
                                    }
                                    eTermEncode.Encropy(buffer, buffer2);
                                    this.SendCmd(this.lss.LoginStep2(buffer2));
                                }
                                else
                                {
                                    this.m_ClientSocket.Disconnect();
                                    return;
                                }
                                this.m_LoginState = StateClass.LoginState.LoginStep3;
                                this.SendCmd(this.lss.LoginStep3());
                            }
                            else if (this.eTerminalType == TerminalType.eTerm)
                            {
                                this.SendCmd(this.lss.LoginStep3());
                            }
                            else if (this.eTerminalType == TerminalType.iTerm)
                            {
                                this.SendCmd(this.lss.iTermLoginStep2());
                                this.m_LoginState = StateClass.LoginState.Logined;
                                this.DoChangeEtermConnectionState(StateClass.ConnectionState.Logined);
                                this.FireOnLogin(this);
                            }
                            else
                            {
                                this.m_LoginState = StateClass.LoginState.UnLogined;
                                this.DoChangeEtermConnectionState(StateClass.ConnectionState.DisConnected);
                            }
                            return;
                        }
                        this.FireOnError(this, new Exception(Encoding.Default.GetString(data, 3, count - 3)));
                        return;

                    case StateClass.LoginState.LoginStep2:
                        this.m_LoginState = StateClass.LoginState.LoginStep3;
                        if (!this.m_ClientSocket.SSL)
                        {
                            if (this.sendLoginStep2)
                            {
                                this.SendCmd(this.lss.LoginStep2());
                            }
                            else if (this.AutoSI && (this.SIText.Trim() != ""))
                            {
                                Thread.Sleep(0x3e8);
                                packet = new CmdPacket(this.SIText.Trim(), null);
                                packet.EcChannel = this;
                                this.m_ClientSocket.Send(packet.EncodeCmdBytes);
                                this.m_LoginState = StateClass.LoginState.LoginStep4;
                            }
                            else
                            {
                                this.m_LoginState = StateClass.LoginState.Logined;
                                this.DoChangeEtermConnectionState(StateClass.ConnectionState.Logined);
                                this.FireOnLogin(this);
                                this.sendLoginStep2 = false;
                                this.sendLoginStep2 = true;
                            }
                            return;
                        }
                        return;

                    case StateClass.LoginState.LoginStep3:
                        if (!this.AutoSI || !(this.SIText.Trim() != ""))
                        {
                            this.DoChangeEtermConnectionState(StateClass.ConnectionState.Logined);
                            this.FireOnLogin(this);
                            this.sendLoginStep2 = false;
                            this.m_LoginState = StateClass.LoginState.Logined;
                            return;
                        }
                        packet = new CmdPacket(this.SIText.Trim(), null);
                        packet.EcChannel = this;
                        this.m_ClientSocket.Send(packet.EncodeCmdBytes);
                        this.m_LoginState = StateClass.LoginState.LoginStep4;
                        return;

                    case StateClass.LoginState.LoginStep4:
                        this.DoChangeEtermConnectionState(StateClass.ConnectionState.Logined);
                        this.FireOnLogin(this);
                        this.sendLoginStep2 = false;
                        this.m_LoginState = StateClass.LoginState.Logined;
                        return;
                }
            }
        }

        internal virtual void StreamParserOnStreamElement(object sender, CmdResult e)
        {
            this.FireOnReadText(this, e);
            if (e.CmdPacket == null)
            {
                e.CmdPacket = this.CurrentCmdPacket;
                if (e.CmdPacket == null)
                {
                    return;
                }
            }
            try
            {
                if ((e.Data.ToUpper().Contains("SIGN IN") && this.AutoSI) && (this.SIText.Trim() != ""))
                {
                    CmdPacket packet = new CmdPacket(this.SIText.Trim(), null);
                    packet.EcChannel = this;
                    this.CurrentCmdPacket.SubCmdPacket = packet;
                    this.CurrentCmdPacket.Repeat = false;
                    this.continunextcmd.Set();
                    return;
                }
            }
            catch (Exception)
            {
            }
            if (this.CurrentCmdPacket.Evaluator != null)
            {
                this.CurrentCmdPacket.Evaluator(e);
            }
            if (!e.DiscardResult)
            {
                this.tempfullpacket.Append(e.Data);
            }
            if (((this.CurrentCmdPacket.SubCmdPacket == null) && !this.CurrentCmdPacket.Repeat) && (this.ParentCmdPacket.CB != null))
            {
                e.Data = this.tempfullpacket.ToString();
                this.ParentCmdPacket.CB(this, e);
                this.tempfullpacket.Remove(0, this.tempfullpacket.Length);
            }
            this.continunextcmd.Set();
        }

        internal virtual void StreamParserOnStreamError(object sender, Exception ex)
        {
            this.FireOnError(sender, ex);
        }

        private void tKeepAlive_Elapsed(object sender, EventArgs e)
        {
            this.KeepAlive();
        }

        private void tReConnect_Elapsed(object sender, EventArgs e)
        {
            this.ReConnect();
        }

        public bool AutoReConnect
        {
            get
            {
                return this.autoreconnect;
            }
            set
            {
                this.autoreconnect = value;
            }
        }

        public int AutoReConnectInterval
        {
            get
            {
                return this.autoreconnectinterval;
            }
            set
            {
                this.autoreconnectinterval = value;
            }
        }

        public bool AutoSI
        {
            get
            {
                return this.autosi;
            }
            set
            {
                this.autosi = value;
            }
        }

        public string ChkCode
        {
            get
            {
                return this.chkcode;
            }
            set
            {
                this.chkcode = value;
            }
        }

        public long ConnectTimeout
        {
            get
            {
                return this.m_ConnectTimeout;
            }
            set
            {
                this.m_ConnectTimeout = value;
            }
        }

        public Packet CurrentCmdPacket
        {
            get
            {
                return this.currentcmdpacket;
            }
        }

        public TerminalType eTerminalType
        {
            get
            {
                return this.eterminaltype;
            }
            set
            {
                this.eterminaltype = value;
            }
        }

        public int ExeInterval
        {
            get
            {
                return this.exeinterval;
            }
            set
            {
                this.exeinterval = value;
            }
        }

        public bool Is3In1
        {
            get
            {
                return this.is3in1;
            }
            set
            {
                this.is3in1 = value;
            }
        }

        public bool KeepAlived
        {
            set
            {
                this.bKeepAlive = value;
            }
        }

        public bool KeepReconnect
        {
            get
            {
                return this.keepreconnect;
            }
            set
            {
                this.keepreconnect = value;
            }
        }

        public string KeyLogin
        {
            set
            {
                this.keylogin = value;
            }
        }

        public byte[] LoginByte
        {
            get
            {
                return this.loginByte;
            }
            set
            {
                this.loginByte = value;
            }
        }

        public Packet ParentCmdPacket
        {
            get
            {
                return this.parentcmdpacket;
            }
        }

        public string PassWord
        {
            get
            {
                return this.password;
            }
            set
            {
                this.password = value;
            }
        }

        public int Port
        {
            get
            {
                return this.port;
            }
            set
            {
                this.port = value;
            }
        }

        public bool RefreshChkCode
        {
            get
            {
                return this.refreshchkcode;
            }
            set
            {
                this.refreshchkcode = value;
            }
        }

        public StringBuilder ResultBuffer
        {
            get
            {
                return this.tempfullpacket;
            }
        }

        public int SendNoResponseInterval
        {
            get
            {
                return this.m_ClientSocket.SendNoResponseInterval;
            }
            set
            {
                this.m_ClientSocket.SendNoResponseInterval = value;
            }
        }

        public string Server
        {
            get
            {
                return this.server;
            }
            set
            {
                this.server = value;
            }
        }

        public string SIText
        {
            get
            {
                return this.sitext;
            }
            set
            {
                this.sitext = value;
            }
        }

        public bool Ssl
        {
            get
            {
                return this.ssl;
            }
            set
            {
                this.ssl = value;
            }
        }

        public string TempResultBuffer
        {
            get
            {
                return this.tempfullpacket.ToString();
            }
        }

        public string UserName
        {
            get
            {
                return this.username;
            }
            set
            {
                this.username = value;
            }
        }

        public delegate void ChkCodeHandler(object sender, Image i);

        public delegate void CmdCountChangeHandler(object sender, int count);

        public delegate void CmdResultCB(object sender, CmdResult result);

        public delegate void CmdResultHandler(object sender, CmdResult cmdresult);

        public delegate void EtermConnectionStateHandler(object sender, StateClass.ConnectionState state);

        public delegate void LoginInfoHandler(object sender, string username, string password);

        public delegate void PacketHandler(object sender, Packet cmdpacket);

        public enum TerminalType
        {
            eTerm,
            iTerm
        }

        private class WebReturnInfo
        {
            private string statecode = "";
            private Hashtable whc = new Hashtable();

            public WebReturnInfo(string s)
            {
                Match match = new Regex("HTTP/1.1(.*)").Match(s);
                if (match.Success)
                {
                    this.StateCode = match.Groups[1].ToString().Trim();
                }
                Regex regex2 = new Regex("(.*?):(.*)");
                for (Match match2 = regex2.Match(s); match2.Success; match2 = match2.NextMatch())
                {
                    this.WebHeaders.Add(match2.Groups[1].ToString().Trim(), match2.Groups[2].ToString().Trim());
                }
            }

            public string StateCode
            {
                get
                {
                    return this.statecode;
                }
                set
                {
                    this.statecode = value;
                }
            }

            public Hashtable WebHeaders
            {
                get
                {
                    return this.whc;
                }
                set
                {
                    this.whc = value;
                }
            }
        }

        private class WebReturnInfoEx : EtermConnection.WebReturnInfo
        {
            private string securitycode;

            public WebReturnInfoEx(string s) : base(s)
            {
                this.securitycode = "";
                Match match = new Regex(@"name=securitycode\s{1,3}value='(.*?)'").Match(s);
                if (match.Success)
                {
                    this.SecurityCode = match.Groups[1].ToString();
                }
            }

            public string SecurityCode
            {
                get
                {
                    return this.securitycode;
                }
                set
                {
                    this.securitycode = value;
                }
            }
        }

        private class WebReturnInfoExLogin : EtermConnection.WebReturnInfo
        {
            private string password;
            private string username;

            public WebReturnInfoExLogin(string s) : base(s)
            {
                this.username = "";
                this.password = "";
                Match match = new Regex(@"Table1.Connect\('(.*?)','(.*)'").Match(s);
                if (match.Success)
                {
                    this.Username = match.Groups[1].ToString();
                    this.Password = match.Groups[2].ToString();
                }
            }

            public string Password
            {
                get
                {
                    return this.password;
                }
                set
                {
                    this.password = value;
                }
            }

            public string Username
            {
                get
                {
                    return this.username;
                }
                set
                {
                    this.username = value;
                }
            }
        }
    }
}
